package com.shop2cn.iapi.sqoptrade.testcase;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import org.apache.http.client.ClientProtocolException;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.experimental.categories.Category;

import com.shop2cn.iapi.shenqisettlement.parameter.bean.AgentProductBean;
import com.shop2cn.iapi.sqoptrade.parameter.req.UserConfirmApplyRefundReq;
import com.shop2cn.iapi.sqoptrade.resp.Order;
import com.shop2cn.iapi.sqoptrade.resp.TradingServiceResp;
import com.shop2cn.iapi.sqoptrade.service.UserConfirmApplyRefundCall;
import com.ymatou.iapi.synctrade.service.TradingSyncService;
import com.ymt.core.tool.Logger;
import com.ymt.utils.annotation.TestCase;
import com.ymt.utils.annotation.TestSuite;
import com.ymt.utils.tag.P1;
import com.ymttest.business.service.AccountCallServiceV2;
import com.ymttest.business.service.SQPayGateWayCallService;
import com.ymttest.business.service.shenqi.DGSQBaseService;
import com.ymttest.business.service.shenqi.DGSQBuildProxyChainCallService;
import com.ymttest.business.service.shenqi.RefundService;
import com.ymttest.business.service.shenqi.ShenqiSettlementService;
import com.ymttest.business.service.shenqi.SqPretradeService;
import com.ymttest.business.service.shenqi.SqTradingMqService;
import com.ymttest.business.service.shenqi.SqTradingCallService;
import com.ymttest.business.service.shenqi.bean.ShenqiUserSet;
import com.ymttest.database.sharding.db.sharding.model.OrderDetailPo;
import com.ymttest.database.sharding.db.sharding.model.OrderDetailSubCodePo;
import com.ymttest.database.sharding.db.sharding.model.OrderPo;
import com.ymttest.database.sharding.db.sharding.model.PaymentPo;
import com.ymttest.database.sharding.db.sharding.model.RefundBillPo;
import com.ymttest.database.sharding.db.sharding.model.UserRefundFundDetailPo;
import com.ymttest.database.sharding.db.sqlwapper.OrderShardingWapper;
import com.ymttest.utils.EnvSetup;

/**
 * 申请退货退款接口 FreeMaker Template自动生成代码
 */
@TestSuite
@Ignore
public class Ts_SqUserConfirmApplyRefund {

	private static UserConfirmApplyRefundReq userConfirmApplyRefundReq;
	private static UserConfirmApplyRefundCall userConfirmApplyRefundCall;

	private static OrderShardingWapper orderShardingWapper = new OrderShardingWapper();

	private static long autotest_goodsOwnerId = Long.valueOf(EnvSetup
			.getData("autotest_goodsOwnerId"));
	
	private static long cdfMembergoodsOwnerId = ShenqiUserSet.cdfMembergoodsOwnerId;
	private static long virtualCoinGoodsOwnerId = ShenqiUserSet.virtualCoinGoodsOwnerId;
	private static long multiCDFCodeGoodsOwnerId = ShenqiUserSet.multiCDFCodeGoodsOwnerId;

	@BeforeClass
	public static void setUp() {
		Logger.createResultFile("神器用户申请退货退款接口");

		String accountid1;
		try {
			accountid1 = AccountCallServiceV2.getAccountId(20238699);
			AccountCallServiceV2.resetAccount(accountid1, new BigDecimal(
					9000000), new BigDecimal(0));
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	@Before
	public void caseUp() {

		userConfirmApplyRefundReq = new UserConfirmApplyRefundReq();
		userConfirmApplyRefundCall = new UserConfirmApplyRefundCall();
	}

	@AfterClass
	public static void tearDown() {
		Logger.generateResult(userConfirmApplyRefundCall.getOpurl());
	}

	@After
	public void caseDown() {
		Logger.end();
		orderShardingWapper.activeDeadCommunicationsLink(orderShardingWapper);
	}

	private void buildVerifyData(OrderPo orderPo,
			BigDecimal productRefundAmount, BigDecimal taxRefundAmount,
			BigDecimal freightRefundAmount, Integer refundCount,
			String catalogId, Boolean isAllRefunded, String currency) {

		Long orderId = orderPo.getOrderId();
		boolean isAccountPaid = false;

		RefundBillPo expectedRefundBillPo = new RefundBillPo();

		BigDecimal totalAmount = productRefundAmount.add(taxRefundAmount).add(
				freightRefundAmount);

		expectedRefundBillPo.setCatalogId(catalogId);
		expectedRefundBillPo.setTotalAmount(totalAmount);
		expectedRefundBillPo.setProductCount(refundCount);

		expectedRefundBillPo
				.setFreight(freightRefundAmount);
		expectedRefundBillPo.setOrderId(orderPo.getOrderId());
		expectedRefundBillPo.setUserId(orderPo.getUserId());
		expectedRefundBillPo.setSellerId(orderPo.getGoodsOwnerId());
		expectedRefundBillPo.setTopspeedRefund(false);
		expectedRefundBillPo.setAfterReceiving(false);
		expectedRefundBillPo.setRefundBillStatus(10);
		expectedRefundBillPo.setTax(taxRefundAmount);
		expectedRefundBillPo.setProductAmount(productRefundAmount);
		expectedRefundBillPo.setReturnStockStatus(2);
		
		if (orderPo.getAccountPaidAmount().compareTo(BigDecimal.ZERO) == 1)
			isAccountPaid = true;
		else
			isAccountPaid = false;
		
		if (isAccountPaid) {
			
			expectedRefundBillPo.setAccountAmount(totalAmount);
			expectedRefundBillPo.setThirdpartyAmount(BigDecimal.ZERO);
		} else {
			
			expectedRefundBillPo.setAccountAmount(BigDecimal.ZERO);
			expectedRefundBillPo.setThirdpartyAmount(totalAmount);
		}
		
		expectedRefundBillPo.setRefundStatus(1);
		
		List<RefundBillPo> refundBillList = orderShardingWapper.selectRefundBillListByOrderId(orderId);
		
		RefundBillPo actualRefundBillPo = refundBillList
				.stream()
				.filter(refundBillPo -> refundBillPo.getCatalogId().equalsIgnoreCase(catalogId))
				.collect(Collectors.toList()).get(0);

		RefundService.verifyRefundBillDb(expectedRefundBillPo,
				actualRefundBillPo);
		
		BigDecimal realSubmitAmount = null;
		
		UserRefundFundDetailPo expectedUserRefundFundDetailPo = new UserRefundFundDetailPo();

		expectedUserRefundFundDetailPo.setOrderId(orderId);
		expectedUserRefundFundDetailPo.setBizNo(isAllRefunded ? orderId
				.toString() : actualRefundBillPo.getRefundBillNo());
		expectedUserRefundFundDetailPo.setThirdpartyDiscount(BigDecimal.ZERO);
		expectedUserRefundFundDetailPo.setPaymentId(orderPo.getPaymentId());
		expectedUserRefundFundDetailPo.setRetryTimes(0);
		expectedUserRefundFundDetailPo.setMemo("0");
		expectedUserRefundFundDetailPo.setRebateAmount(BigDecimal.ZERO);
		expectedUserRefundFundDetailPo.setIsShenqi(true);
		
		List<UserRefundFundDetailPo> userRefundFundDetailList = orderShardingWapper
				.selectUserRefundFundDetailListByPaymentId(orderPo
						.getPaymentId());
		
		if (null != currency) {
			
			PaymentPo paymentPo = orderShardingWapper.selectPaymentById(orderPo.getPaymentId());
			
			if (currency.equalsIgnoreCase("CNY")
					&& paymentPo.getGatewayPayType().equalsIgnoreCase("6010"))
				realSubmitAmount = paymentPo.getRealSubmitRmbAmount();
			else
				// 如果这个退款单退了所有的商品
				if (isAllRefunded && userRefundFundDetailList.size() == 1)
					realSubmitAmount = paymentPo.getRealSubmitForeignAmount();
				else
					realSubmitAmount = totalAmount.multiply(
							paymentPo.getRmbVsRealSubmitForeignRate()).setScale(2,
							BigDecimal.ROUND_DOWN);
		}
		
		expectedUserRefundFundDetailPo
				.setThirdpartyAmount(realSubmitAmount == null ? totalAmount
						: realSubmitAmount);
		
		UserRefundFundDetailPo actualUserRefundFundDetailPo = new UserRefundFundDetailPo();

		actualUserRefundFundDetailPo = userRefundFundDetailList
				.stream()
				.filter(po -> po.getBizNo().equalsIgnoreCase(
						String.valueOf(userConfirmApplyRefundReq.getOrderId())))
				.collect(Collectors.toList()).get(0);

		expectedUserRefundFundDetailPo.setBizType(1);
		
		if (isAccountPaid) {
			
			expectedUserRefundFundDetailPo.setAccountAmount(realSubmitAmount);
			expectedUserRefundFundDetailPo.setAccountRefundStatus(4);
			expectedUserRefundFundDetailPo.setThirdpartyAmount(BigDecimal.ZERO);
			expectedUserRefundFundDetailPo.setThirdpartyRefundStatus(-1);
		} else {
			
			expectedUserRefundFundDetailPo.setAccountAmount(BigDecimal.ZERO);
			expectedUserRefundFundDetailPo.setAccountRefundStatus(-1);
			expectedUserRefundFundDetailPo.setThirdpartyAmount(realSubmitAmount);
			expectedUserRefundFundDetailPo.setThirdpartyRefundStatus(4);
		}
		
		RefundService.verifyUserRefundFundDetailDb(
				expectedUserRefundFundDetailPo, actualUserRefundFundDetailPo);
		
		// 一品多码商品
		if (orderPo.getGoodsOwnerId() == multiCDFCodeGoodsOwnerId) {
			
			List<OrderDetailSubCodePo> orderDetailSubCodePoList = orderShardingWapper
					.selectOrderDetailSubCodebyOrderId(orderId);
			
			for (OrderDetailSubCodePo orderDetailSubCodePo : orderDetailSubCodePoList) {
				
				Logger.verifyEquals(orderDetailSubCodePo.getProductCount(),
						orderDetailSubCodePo.getRefundProductCount(),
						String.format("验证%s子码退款数量", orderDetailSubCodePo.getCatalogId()));
			}
		}
	}

	/**
	 * 
	 * @param userId
	 * @param isDelivered
	 * @param currency (特殊情况时，提交给网关的币种)
	 */
	private void verify(Long userId, Boolean isDelivered, String currency) {

		OrderPo orderPo = orderShardingWapper
				.selectOrderbyOrderId(userConfirmApplyRefundReq.getOrderId());

		List<OrderDetailPo> orderDetailPoList = orderShardingWapper
				.selectOrderDetailbyOrderId(userConfirmApplyRefundReq
						.getOrderId());

		Boolean isAllRefunded = RefundService.isAllRefunded(
				orderPo.getOrderId(), orderDetailPoList);

		for (OrderDetailPo orderDetailPo : orderDetailPoList) {
			
			this.buildVerifyData(orderPo, RefundService
					.getOrderDetailPaidAmountExcludeFreight(orderDetailPo,
							orderDetailPo.getProductCount(), true),
					RefundService.getOrderDetailTaxFeeAmount(orderDetailPo,
							orderDetailPo.getProductCount()), RefundService
							.getMaxCanRefundFreight(orderDetailPo,
									orderDetailPo.getFreight()), orderDetailPo
							.getProductCount(), orderDetailPo.getCatalogId(),
					isAllRefunded, currency);
		}

		if (isAllRefunded) {

			Logger.comment("买家申请退款");

			// 买家退款12
			if (!isDelivered) {
				Logger.verifyEquals(12, orderPo.getOrderStatus(),
						"验证OrderStatus");

				Logger.verifyEquals("买家申请退款",
						orderPo.getCancelReason(), "验证CancelReason");
			}
			
			Logger.verifyEquals(2, orderPo.getReturnProductStatus(), "验证ReturnProductStatus");
		} else {
			
			Logger.verifyEquals(1, orderPo.getReturnProductStatus(), "验证ReturnProductStatus");
		}
	}

	@Test
	@Category({ P1.class })
	@TestCase
	public void Tc_UserConfirmApplyRefund_001() {
		Logger.start(true, "直销商整单退款，hipopay已支付，用户申请退货退款成功");
		try {

			AgentProductBean productBean = DGSQBuildProxyChainCallService
					.createProxychain((int) autotest_goodsOwnerId, 0, false,
							false);

			TradingServiceResp placeOrderResp = SqTradingCallService
					.placeOrderWithPurchaserIdcardId(productBean, 3L);

			Order order = placeOrderResp.getOrderList().get(0);

			Long userId = placeOrderResp.getUserId();
			BigDecimal totalPrice = placeOrderResp.getPayableAmount();

			long orderId = order.getOrderId();

			// 支付订单
			Long thirdTradingId = SqTradingCallService.payOrder(userId,
					placeOrderResp.getTradingId());

			// 支付网关支付回调交易
			SQPayGateWayCallService.DGSQNotifyCall(
					String.valueOf(thirdTradingId),
					totalPrice.subtract(BigDecimal.ZERO).toString(),
					userId.intValue(), BigDecimal.ZERO.toPlainString());

			Thread.sleep(5000);

			Long paymentId = orderShardingWapper.selectOrderbyOrderId(orderId)
					.getPaymentId();

			userConfirmApplyRefundReq.setOrderId(orderId);
			userConfirmApplyRefundReq.setUserId(userId);

			userConfirmApplyRefundCall.setData(userConfirmApplyRefundReq);
			userConfirmApplyRefundCall.callService();

			// 退款提交到网关
			UserRefundFundDetailPo record = new UserRefundFundDetailPo();

			Calendar calendar = Calendar.getInstance();
			calendar.setTime(new Date());
			calendar.add(Calendar.MINUTE, -6);

			record.setPaymentId(paymentId);
			record.setUpdateTime(calendar.getTime());

			orderShardingWapper.userRefundFundDetailMapper
					.updateByPrimaryKeySelective(record);

			RefundService.supplementRefund(orderId);

			// 支付网关退款回调
			SQPayGateWayCallService.refundNotifyCall("13", paymentId.toString(),
					userId.intValue());

			Logger.comment("userId: " + userId + ", orderId: " + orderId);
			Logger.verifyEquals("true",
					userConfirmApplyRefundCall.getString("success"), "验证success");

			this.verify(userId, false, null);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category({ P1.class })
	@TestCase
	public void Tc_UserConfirmApplyRefund_002() {
		Logger.start(false, "用户申请退货退款,订单号不存在");
		try {

			userConfirmApplyRefundReq.setOrderId(11111L);
			userConfirmApplyRefundReq.setUserId(4214L);

			userConfirmApplyRefundCall.setData(userConfirmApplyRefundReq);
			userConfirmApplyRefundCall.callService();

			Logger.verifyEquals("false",
					userConfirmApplyRefundCall.getString("success"), "验证success");

			Logger.verifyEquals("ErrOrderNotExists",
					userConfirmApplyRefundCall.getString("errorCode"), "验证返回码");

			Logger.verifyEquals(
					String.format("订单不存在", userConfirmApplyRefundReq.getOrderId()),
					userConfirmApplyRefundCall.getString("errorMessage"),
					"验证errorMessage");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category({ P1.class })
	@TestCase
	public void Tc_UserConfirmApplyRefund_003() {
		Logger.start(true, "同一退款单,退款完成，重复申请退款");
		try {

			AgentProductBean productBean = DGSQBuildProxyChainCallService
					.createProxychain((int) autotest_goodsOwnerId, 0, false,
							false);
			TradingServiceResp placeOrderResp = SqTradingCallService
					.orderRefundSuccess(productBean);

			userConfirmApplyRefundReq.setOrderId(placeOrderResp.getOrderList().get(0).getOrderId());
			userConfirmApplyRefundReq.setUserId(placeOrderResp.getUserId());

			userConfirmApplyRefundCall.setData(userConfirmApplyRefundReq);
			userConfirmApplyRefundCall.callService();

			Thread.sleep(2000);

			Logger.verifyEquals("false",
					userConfirmApplyRefundCall.getString("success"), "验证success");

			Logger.verifyEquals("ERR_ORDER_CANCELLED",
					userConfirmApplyRefundCall.getString("errorCode"), "验证返回码");

			Logger.verifyEquals(
					String.format("当前状态不能退货退款", userConfirmApplyRefundReq.getOrderId()),
					userConfirmApplyRefundCall.getString("errorMessage"),
					"验证errorMessage");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category({ P1.class })
	@TestCase
	public void Tc_UserConfirmApplyRefund_004() {
		Logger.start(true, "代理订单整单退款，hipopay已支付，用户申请退货退款成功");
		try {

			AgentProductBean productBean = DGSQBuildProxyChainCallService
					.createProxychain((int) autotest_goodsOwnerId, 1, false,
							false);

			TradingServiceResp placeOrderResp = SqTradingCallService
					.placeOrder(productBean, autotest_goodsOwnerId);

			Order order = placeOrderResp.getOrderList().get(0);

			Long userId = placeOrderResp.getUserId();
			BigDecimal totalPrice = placeOrderResp.getPayableAmount();
			
			long orderId = order.getOrderId();
			
			SqTradingMqService.updateLiveOrder(false, orderId);

			// 支付订单
			Long thirdTradingId = SqTradingCallService.payOrder(userId,
					placeOrderResp.getTradingId());

			// 支付网关支付回调交易
			SQPayGateWayCallService.DGSQNotifyCall(
					String.valueOf(thirdTradingId),
					totalPrice.subtract(BigDecimal.ZERO).toString(),
					userId.intValue(), BigDecimal.ZERO.toPlainString());

			Thread.sleep(5000);

			Long paymentId = orderShardingWapper.selectOrderbyOrderId(orderId)
					.getPaymentId();
			
			PaymentPo payment = orderShardingWapper.selectPaymentById(paymentId);

			ShenqiSettlementService.onHpSettled(paymentId, payment, null, 1);

			userConfirmApplyRefundReq.setOrderId(orderId);
			userConfirmApplyRefundReq.setUserId(userId);

			userConfirmApplyRefundCall.setData(userConfirmApplyRefundReq);
			userConfirmApplyRefundCall.callService();

			// 退款提交到网关
			UserRefundFundDetailPo record = new UserRefundFundDetailPo();

			Calendar calendar = Calendar.getInstance();
			calendar.setTime(new Date());
			calendar.add(Calendar.MINUTE, -6);

			record.setPaymentId(paymentId);
			record.setUpdateTime(calendar.getTime());

			orderShardingWapper.userRefundFundDetailMapper
					.updateByPrimaryKeySelective(record);

			RefundService.supplementRefund(orderId);

			// 支付网关退款回调
			SQPayGateWayCallService.refundNotifyCall("13", paymentId.toString(),
					userId.intValue());

			Logger.comment("userId: " + userId + ", orderId: " + orderId);
			Logger.verifyEquals("true",
					userConfirmApplyRefundCall.getString("success"), "验证success");

			this.verify(userId, false, null);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category({ P1.class })
	@TestCase
	public void Tc_UserConfirmApplyRefund_005() {
		Logger.start(true, "分销小店订单整单退款，hipopay已支付，用户申请退货退款成功");
		try {

			Integer mchId = DGSQBaseService.createIndependenceMch("USA");

			AgentProductBean productBean = DGSQBuildProxyChainCallService
					.createIndependenceProxychain(mchId, 2, true, false);

			TradingServiceResp placeOrderResp = SqTradingCallService
					.placeOrder(productBean, mchId);

			Order order = placeOrderResp.getOrderList().get(0);
			Long userId = placeOrderResp.getUserId();
			BigDecimal totalPrice = placeOrderResp.getPayableAmount();

			long orderId = order.getOrderId();
			
			SqTradingMqService.updateLiveOrder(false, orderId);

			// 支付订单
			Long thirdTradingId = SqTradingCallService.payOrder(userId,
					placeOrderResp.getTradingId());

			// 支付网关支付回调交易
			SQPayGateWayCallService.DGSQNotifyCall(
					String.valueOf(thirdTradingId),
					totalPrice.subtract(BigDecimal.ZERO).toString(),
					userId.intValue(), BigDecimal.ZERO.toPlainString());

			Thread.sleep(5000);

			Long paymentId = orderShardingWapper.selectOrderbyOrderId(orderId)
					.getPaymentId();
			
			PaymentPo payment = orderShardingWapper.selectPaymentById(paymentId);

			ShenqiSettlementService.onHpSettled(paymentId, payment, null, 1);

			userConfirmApplyRefundReq.setOrderId(orderId);
			userConfirmApplyRefundReq.setUserId(userId);

			userConfirmApplyRefundCall.setData(userConfirmApplyRefundReq);
			userConfirmApplyRefundCall.callService();

			// 退款提交到网关
			UserRefundFundDetailPo record = new UserRefundFundDetailPo();

			Calendar calendar = Calendar.getInstance();
			calendar.setTime(new Date());
			calendar.add(Calendar.MINUTE, -6);

			record.setPaymentId(paymentId);
			record.setUpdateTime(calendar.getTime());

			orderShardingWapper.userRefundFundDetailMapper
					.updateByPrimaryKeySelective(record);

			RefundService.supplementRefund(orderId);

			// 支付网关退款回调
			SQPayGateWayCallService.refundNotifyCall("13", paymentId.toString(),
					userId.intValue());

			Logger.comment("userId: " + userId + ", orderId: " + orderId);
			Logger.verifyEquals("true",
					userConfirmApplyRefundCall.getString("success"), "验证success");

			this.verify(userId, false, null);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category({ P1.class })
	@TestCase
	public void Tc_UserConfirmApplyRefund_009() {
		Logger.start(true, "盛付通支持整单退款,退款成功");
		try {

			AgentProductBean productBean = DGSQBuildProxyChainCallService
					.createProxychain((int) autotest_goodsOwnerId, 0, false,
							false);

			TradingServiceResp placeOrderResp = SqTradingCallService
					.placeOrderWithPurchaserIdcardId(productBean, 3L);

			Order order = placeOrderResp.getOrderList().get(0);

			Long userId = placeOrderResp.getUserId();

			long orderId = order.getOrderId();

			BigDecimal amount = placeOrderResp.getPayableAmount();

			// 支付订单
			Long thirdTradingId = SqTradingCallService.payOrder(userId,
					placeOrderResp.getTradingId(), "wxsqBuyer", "6010");

			// 支付网关支付回调交易
			SQPayGateWayCallService.DGSQNotifyCall(
					String.valueOf(thirdTradingId),
					amount.subtract(BigDecimal.ZERO).toString(),
					userId.intValue(), BigDecimal.ZERO.toPlainString(), 6010);

			Thread.sleep(5000);

			Long paymentId = orderShardingWapper.selectOrderbyOrderId(orderId)
					.getPaymentId();

			userConfirmApplyRefundReq.setOrderId(orderId);
			userConfirmApplyRefundReq.setUserId(userId);

			userConfirmApplyRefundCall.setData(userConfirmApplyRefundReq);
			userConfirmApplyRefundCall.callService();

			// 退款提交到网关
			UserRefundFundDetailPo record = new UserRefundFundDetailPo();

			Calendar calendar = Calendar.getInstance();
			calendar.setTime(new Date());
			calendar.add(Calendar.MINUTE, -6);

			record.setPaymentId(paymentId);
			record.setUpdateTime(calendar.getTime());

			orderShardingWapper.userRefundFundDetailMapper
					.updateByPrimaryKeySelective(record);

			RefundService.supplementRefund(orderId);

			// 支付网关退款回调
			SQPayGateWayCallService.refundNotifyCall("13", paymentId.toString(),
					userId.intValue());

			Logger.comment("userId: " + userId + ", orderId: " + orderId);
			Logger.verifyEquals("true",
					userConfirmApplyRefundCall.getString("success"), "验证success");

			this.verify(userId, false, null);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category({ P1.class })
	@TestCase
	public void Tc_UserConfirmApplyRefund_010() {
		Logger.start(true, "人民币标价商品，商户不允许收取人民币，hipopay支付,用户整单退款成功");
		try {

			AgentProductBean productBean = DGSQBuildProxyChainCallService
					.createProxychain((int) 500956988, 0, false,
							false);

			TradingServiceResp placeOrderResp = SqTradingCallService
					.placeOrder(productBean, null, 1, 500956988L,
							productBean.getCurrency());
			
			String currency = "USD";

			Order order = placeOrderResp.getOrderList().get(0);

			Long userId = placeOrderResp.getUserId();

			long orderId = order.getOrderId();

			BigDecimal amount = placeOrderResp.getPayableAmount();

			// 支付订单
			Long thirdTradingId = SqTradingCallService.payOrder(userId,
					placeOrderResp.getTradingId(), "wxsqBuyer", "6000");

			// 根据人民币离岸汇率计算
			BigDecimal exchangeRmbRate = DGSQBaseService.getCurrencyConfig(
					"USD").getExchangeRmbRate();

			amount = amount.multiply(
					BigDecimal.ONE.divide(exchangeRmbRate, 7,
							BigDecimal.ROUND_UP)).setScale(2,
					BigDecimal.ROUND_UP);

			SQPayGateWayCallService.DGSQNotifyCall(
					String.valueOf(thirdTradingId),
					amount.subtract(BigDecimal.ZERO).toString(),
					userId.intValue(), BigDecimal.ZERO.toPlainString(),
					currency, currency);

			TradingSyncService.getSyncResult(orderId);

			Thread.sleep(5000);

			Long paymentId = orderShardingWapper.selectOrderbyOrderId(orderId)
					.getPaymentId();
			
			userConfirmApplyRefundReq.setOrderId(orderId);
			userConfirmApplyRefundReq.setUserId(userId);

			userConfirmApplyRefundCall.setData(userConfirmApplyRefundReq);
			userConfirmApplyRefundCall.callService();
			
			// 退款提交到网关
			UserRefundFundDetailPo record = new UserRefundFundDetailPo();

			Calendar calendar = Calendar.getInstance();
			calendar.setTime(new Date());
			calendar.add(Calendar.MINUTE, -6);

			record.setPaymentId(paymentId);
			record.setUpdateTime(calendar.getTime());

			orderShardingWapper.userRefundFundDetailMapper
					.updateByPrimaryKeySelective(record);

			RefundService.supplementRefund(orderId);

			// 支付网关退款回调
			SQPayGateWayCallService.refundNotifyCall("13", paymentId.toString(),
					userId.intValue());

			Logger.comment("userId: " + userId + ", orderId: " + orderId);
			Logger.verifyEquals("true",
					userConfirmApplyRefundCall.getString("success"), "验证success");

			this.verify(userId, false, currency);
			
		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category({ P1.class })
	@TestCase
	public void Tc_UserConfirmApplyRefund_012() {
		Logger.start(true, "直销商发货后,用户整单退款失败");
		try {

			AgentProductBean productBean = DGSQBuildProxyChainCallService
					.createProxychain((int) autotest_goodsOwnerId, 0, false,
							false);

			TradingServiceResp placeOrderResp = SqTradingCallService
					.placeOrder1(productBean, autotest_goodsOwnerId);

			Order order = placeOrderResp.getOrderList().get(0);

			long sellerId = order.getSellerId();
			Long userId = placeOrderResp.getUserId();

			long orderId = order.getOrderId();
			BigDecimal amount = placeOrderResp.getPayableAmount();

			// 支付订单
			Long thirdTradingId = SqTradingCallService.payOrder(userId,
					placeOrderResp.getTradingId());

			// 支付网关支付回调交易
			SQPayGateWayCallService.DGSQNotifyCall(
					String.valueOf(thirdTradingId),
					amount.subtract(BigDecimal.ZERO).toString(),
					userId.intValue(), BigDecimal.ZERO.toPlainString());

			Thread.sleep(5000);

			// 卖家接单
			SqTradingCallService.sellerAcceptOrder(sellerId, orderId);

			SqTradingCallService.delivery(autotest_goodsOwnerId, orderId,
					null, null);

			userConfirmApplyRefundReq.setOrderId(orderId);
			userConfirmApplyRefundReq.setUserId(userId);

			userConfirmApplyRefundCall.setData(userConfirmApplyRefundReq);
			userConfirmApplyRefundCall.callService();

			Logger.verifyEquals("false",
					userConfirmApplyRefundCall.getString("success"), "验证success");

			Logger.verifyEquals("ERR_ORDER_CANCELLED",
					userConfirmApplyRefundCall.getString("errorCode"), "验证返回码");

			Logger.verifyEquals(
					String.format("当前状态不能退货退款",
							userConfirmApplyRefundReq.getOrderId()),
							userConfirmApplyRefundCall.getString("errorMessage"),
					"验证errorMessage");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category({ P1.class })
	@TestCase
	@Ignore
	public void Tc_UserConfirmApplyRefund_013() {
		Logger.start(true, "代购神器，直销商，连锁店模式，已接单，已结算, 用户整单退款成功");
		try {

			// 创建订单
			Logger.comment("前置数据准备");

			AgentProductBean productBean = DGSQBuildProxyChainCallService
					.createProxychain(ShenqiUserSet.chainStoreGoodsOwnerId.intValue(), 0, false);
			TradingServiceResp placeOrderResp = SqTradingCallService
					.placeChainStoreOrder(productBean, ShenqiUserSet.chainStoreGoodsOwnerId,
							productBean.getCurrency());

			Long userId = placeOrderResp.getUserId();
			long orderId = placeOrderResp.getOrderList().get(0).getOrderId();
			BigDecimal totalPrice = placeOrderResp.getPayableAmount();

			// 支付订单
			Long thirdTradingId = SqTradingCallService.payOrder(userId,
					placeOrderResp.getTradingId(), "501476063", "6401");

			// 支付网关支付回调交易
			SQPayGateWayCallService.DGSQNotifyCall(
					String.valueOf(thirdTradingId),
					totalPrice.subtract(BigDecimal.ZERO).toString(),
					userId.intValue(), BigDecimal.ZERO.toPlainString(), 6401);

			TradingSyncService.getSyncResult(orderId);
			Thread.sleep(5000);

			Logger.comment("前置数据准备结束");

			Long paymentId = orderShardingWapper.selectOrderbyOrderId(orderId)
					.getPaymentId();

			userConfirmApplyRefundReq.setOrderId(orderId);
			userConfirmApplyRefundReq.setUserId(userId);

			userConfirmApplyRefundCall.setData(userConfirmApplyRefundReq);
			userConfirmApplyRefundCall.callService();

			// 退款提交到网关
			UserRefundFundDetailPo record = new UserRefundFundDetailPo();

			Calendar calendar = Calendar.getInstance();
			calendar.setTime(new Date());
			calendar.add(Calendar.MINUTE, -6);

			record.setPaymentId(paymentId);
			record.setUpdateTime(calendar.getTime());

			orderShardingWapper.userRefundFundDetailMapper
					.updateByPrimaryKeySelective(record);

			RefundService.supplementRefund(orderId);

			// 支付网关退款回调
			SQPayGateWayCallService.refundNotifyCall("13", paymentId.toString(),
					userId.intValue());

			Logger.comment("userId: " + userId + ", orderId: " + orderId);
			Logger.verifyEquals("true",
					userConfirmApplyRefundCall.getString("success"), "验证success");

			this.verify(userId, false, null);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category({ P1.class })
	@TestCase
	public void Tc_UserConfirmApplyRefund_014() {
		Logger.start(true, "中免大会员整单退款，使用积分，hipopay已支付，用户申请退货退款成功");
		try {

			AgentProductBean productBean = DGSQBuildProxyChainCallService
					.createProxychain((int) cdfMembergoodsOwnerId, 0, false,
							false);

//			TradingServiceResp placeOrderResp = TradingForDGSQCallService
//					.placeOrderWithCDFMember(productBean, cdfMembergoodsOwnerId, 10L);
			
			TradingServiceResp placeOrderResp = SqTradingCallService
					.placeAllPromotionOrderWithCDFMember(productBean, cdfMembergoodsOwnerId, 300L, false);

			Order order = placeOrderResp.getOrderList().get(0);

			Long userId = placeOrderResp.getUserId();
			BigDecimal totalPrice = placeOrderResp.getPayableAmount();

			long orderId = order.getOrderId();

			// 支付订单
			Long thirdTradingId = SqTradingCallService.payOrder(userId,
					placeOrderResp.getTradingId());

			// 支付网关支付回调交易
			SQPayGateWayCallService.DGSQNotifyCall(
					String.valueOf(thirdTradingId),
					totalPrice.subtract(BigDecimal.ZERO).toString(),
					userId.intValue(), BigDecimal.ZERO.toPlainString());

			Thread.sleep(5000);

			Long paymentId = orderShardingWapper.selectOrderbyOrderId(orderId)
					.getPaymentId();

			userConfirmApplyRefundReq.setOrderId(orderId);
			userConfirmApplyRefundReq.setUserId(userId);

			userConfirmApplyRefundCall.setData(userConfirmApplyRefundReq);
			userConfirmApplyRefundCall.callService();

			// 退款提交到网关
			UserRefundFundDetailPo record = new UserRefundFundDetailPo();

			for (int i = 0; i < 2; i++) {
				
				Calendar calendar = Calendar.getInstance();
				calendar.setTime(new Date());
				calendar.add(Calendar.MINUTE, -6 * (i + 10));

				record.setPaymentId(paymentId);
				record.setUpdateTime(calendar.getTime());

				orderShardingWapper.userRefundFundDetailMapper
						.updateByPrimaryKeySelective(record);

				RefundService.supplementRefund(orderId);
				
				Thread.sleep(5000);
			}

			// 支付网关退款回调
			SQPayGateWayCallService.refundNotifyCall("13", paymentId.toString(),
					userId.intValue());

			Logger.comment("userId: " + userId + ", orderId: " + orderId);
			Logger.verifyEquals("true",
					userConfirmApplyRefundCall.getString("success"), "验证success");

			this.verify(userId, false, null);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category({ P1.class })
	@TestCase
	public void Tc_UserConfirmApplyRefund_015() {
		Logger.start(true, "中免大会员整单退款， 不使用积分，hipopay已支付，用户申请退货退款成功");
		try {

			AgentProductBean productBean = DGSQBuildProxyChainCallService
					.createProxychain((int) cdfMembergoodsOwnerId, 0, false,
							false);

			TradingServiceResp placeOrderResp = SqTradingCallService
					.placeOrderWithCDFMember(productBean, cdfMembergoodsOwnerId, 0L);

			Order order = placeOrderResp.getOrderList().get(0);

			Long userId = placeOrderResp.getUserId();
			BigDecimal totalPrice = placeOrderResp.getPayableAmount();

			long orderId = order.getOrderId();

			// 支付订单
			Long thirdTradingId = SqTradingCallService.payOrder(userId,
					placeOrderResp.getTradingId());

			// 支付网关支付回调交易
			SQPayGateWayCallService.DGSQNotifyCall(
					String.valueOf(thirdTradingId),
					totalPrice.subtract(BigDecimal.ZERO).toString(),
					userId.intValue(), BigDecimal.ZERO.toPlainString());

			Thread.sleep(5000);

			Long paymentId = orderShardingWapper.selectOrderbyOrderId(orderId)
					.getPaymentId();

			userConfirmApplyRefundReq.setOrderId(orderId);
			userConfirmApplyRefundReq.setUserId(userId);

			userConfirmApplyRefundCall.setData(userConfirmApplyRefundReq);
			userConfirmApplyRefundCall.callService();

			// 退款提交到网关
			UserRefundFundDetailPo record = new UserRefundFundDetailPo();

			for (int i = 0; i < 2; i++) {
				
				Calendar calendar = Calendar.getInstance();
				calendar.setTime(new Date());
				calendar.add(Calendar.MINUTE, -6 * (i + 10));

				record.setPaymentId(paymentId);
				record.setUpdateTime(calendar.getTime());

				orderShardingWapper.userRefundFundDetailMapper
						.updateByPrimaryKeySelective(record);

				RefundService.supplementRefund(orderId);
				
				Thread.sleep(5000);
			}

			// 支付网关退款回调
			SQPayGateWayCallService.refundNotifyCall("13", paymentId.toString(),
					userId.intValue());

			Logger.comment("userId: " + userId + ", orderId: " + orderId);
			Logger.verifyEquals("true",
					userConfirmApplyRefundCall.getString("success"), "验证success");

			this.verify(userId, false, null);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category({ P1.class })
	@TestCase
	public void Tc_UserConfirmApplyRefund_016() {
		Logger.start(true, "使用代币，用户申请退货退款成功");
		try {

			AgentProductBean productBean = DGSQBuildProxyChainCallService
					.createIndependenceProxychain((int)virtualCoinGoodsOwnerId, 1, false, false);
			
			TradingServiceResp placeOrderResp = SqTradingCallService
					.placeOrderWithUserIdAndSalemanAndGoodsOwnerIdAndIntegral(
							productBean, productBean.getSellerId(), null,
							virtualCoinGoodsOwnerId, null);

			Order order = placeOrderResp.getOrderList().get(0);

			Long userId = placeOrderResp.getUserId();

			long orderId = order.getOrderId();

			BigDecimal useAccountAmount = placeOrderResp.getPayableAmount();
			Long tradingId = placeOrderResp.getTradingId();
			
			// 充值代币
			SqPretradeService.virtualCoinCharge(virtualCoinGoodsOwnerId,
					productBean.getSellerId(), useAccountAmount);

			// 支付订单
			SqTradingCallService.payOrderWithVirtualCoin(userId, tradingId, useAccountAmount);

			Thread.sleep(5000);

			Long paymentId = orderShardingWapper.selectOrderbyOrderId(orderId)
					.getPaymentId();

			userConfirmApplyRefundReq.setOrderId(orderId);
			userConfirmApplyRefundReq.setUserId(userId);

			userConfirmApplyRefundCall.setData(userConfirmApplyRefundReq);
			userConfirmApplyRefundCall.callService();

			// 退款提交到网关
			UserRefundFundDetailPo record = new UserRefundFundDetailPo();

			Calendar calendar = Calendar.getInstance();
			calendar.setTime(new Date());
			calendar.add(Calendar.MINUTE, -6);

			record.setPaymentId(paymentId);
			record.setUpdateTime(calendar.getTime());

			orderShardingWapper.userRefundFundDetailMapper
					.updateByPrimaryKeySelective(record);

			RefundService.supplementRefund(orderId);

			Logger.comment("userId: " + userId + ", orderId: " + orderId);
			Logger.verifyEquals("true",
					userConfirmApplyRefundCall.getString("success"), "验证success");
			
			Thread.sleep(3000);

			this.verify(userId, false, null);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category({ P1.class })
	@TestCase
	public void Tc_UserConfirmApplyRefund_017() {
		Logger.start(true, "中免大会员，组合商品订单，用户申请退货退款成功");
		try {

			long integral = 358L;

			TradingServiceResp placeOrderResp = SqTradingCallService
					.placeCDFMemberComposeProductOrder(cdfMembergoodsOwnerId, integral);

			Order order = placeOrderResp.getOrderList().get(0);
			
			Long userId = placeOrderResp.getUserId();
			long orderId = order.getOrderId();

			BigDecimal amount = placeOrderResp.getPayableAmount();

			// 支付订单
			Long thirdTradingId = SqTradingCallService.payOrder(userId,
					placeOrderResp.getTradingId());

			// 支付网关支付回调交易
			SQPayGateWayCallService.DGSQNotifyCall(
					String.valueOf(thirdTradingId),
					amount.subtract(BigDecimal.ZERO).toString(),
					userId.intValue(), BigDecimal.ZERO.toPlainString());

			Thread.sleep(5000);

			Long paymentId = orderShardingWapper.selectOrderbyOrderId(orderId)
					.getPaymentId();

			userConfirmApplyRefundReq.setOrderId(orderId);
			userConfirmApplyRefundReq.setUserId(userId);

			userConfirmApplyRefundCall.setData(userConfirmApplyRefundReq);
			userConfirmApplyRefundCall.callService();

			// 退款提交到网关，第一次退积分，第二次退金额
			UserRefundFundDetailPo record = new UserRefundFundDetailPo();

			for (int i = 0; i < 3; i++) {

				Calendar calendar = Calendar.getInstance();
				calendar.setTime(new Date());
				calendar.add(Calendar.MINUTE, -6 * (i + 10));

				record.setPaymentId(paymentId);
				record.setUpdateTime(calendar.getTime());

				orderShardingWapper.userRefundFundDetailMapper
						.updateByPrimaryKeySelective(record);

				RefundService.supplementRefund(orderId);

				Thread.sleep(5000);
			}

			// 支付网关退款回调
			SQPayGateWayCallService.refundNotifyCall("13",
					paymentId.toString(), userId.intValue());

			Thread.sleep(3000);

			this.verify(userId, false, null);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category({ P1.class })
	@TestCase
	public void Tc_UserConfirmApplyRefund_018() {
		Logger.start(true, "一品多码商品整单退款，hipopay已支付，用户申请退货退款成功");
		try {

			AgentProductBean productBean = DGSQBuildProxyChainCallService
					.createMultiCodeProxychain((int) multiCDFCodeGoodsOwnerId, false);
			
			TradingServiceResp placeOrderResp = SqTradingCallService
					.placeMultiCDFCodeOrder(productBean, multiCDFCodeGoodsOwnerId);

			Order order = placeOrderResp.getOrderList().get(0);

			Long userId = placeOrderResp.getUserId();
			BigDecimal totalPrice = placeOrderResp.getPayableAmount();

			long orderId = order.getOrderId();

			// 支付订单
			Long thirdTradingId = SqTradingCallService.payOrder(userId,
					placeOrderResp.getTradingId());

			// 支付网关支付回调交易
			SQPayGateWayCallService.DGSQNotifyCall(
					String.valueOf(thirdTradingId),
					totalPrice.subtract(BigDecimal.ZERO).toString(),
					userId.intValue(), BigDecimal.ZERO.toPlainString());

			Thread.sleep(5000);

			Long paymentId = orderShardingWapper.selectOrderbyOrderId(orderId)
					.getPaymentId();

			userConfirmApplyRefundReq.setOrderId(orderId);
			userConfirmApplyRefundReq.setUserId(userId);

			userConfirmApplyRefundCall.setData(userConfirmApplyRefundReq);
			userConfirmApplyRefundCall.callService();

			// 退款提交到网关
			UserRefundFundDetailPo record = new UserRefundFundDetailPo();

			Calendar calendar = Calendar.getInstance();
			calendar.setTime(new Date());
			calendar.add(Calendar.MINUTE, -6);

			record.setPaymentId(paymentId);
			record.setUpdateTime(calendar.getTime());

			orderShardingWapper.userRefundFundDetailMapper
					.updateByPrimaryKeySelective(record);

			RefundService.supplementRefund(orderId);

			// 支付网关退款回调
			SQPayGateWayCallService.refundNotifyCall("13", paymentId.toString(),
					userId.intValue());

			Logger.comment("userId: " + userId + ", orderId: " + orderId);
			Logger.verifyEquals("true",
					userConfirmApplyRefundCall.getString("success"), "验证success");

			this.verify(userId, false, null);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category({ P1.class })
	@TestCase
	public void Tc_UserConfirmApplyRefund_019() {
		Logger.start(true, "直销订单，带有服务费率，用户申请退货退款成功");
		try {

			AgentProductBean productBean = DGSQBuildProxyChainCallService
					.createProxychain((int) autotest_goodsOwnerId, 0, false,
							false);

			TradingServiceResp placeOrderResp = SqTradingCallService
					.placeOrderWithServiceRate(productBean);
			
			Order order = placeOrderResp.getOrderList().get(0);

			Long userId = placeOrderResp.getUserId();
			BigDecimal totalPrice = placeOrderResp.getPayableAmount();
			
			long orderId = order.getOrderId();
			
			SqTradingMqService.updateLiveOrder(false, orderId);

			// 支付订单
			Long thirdTradingId = SqTradingCallService.payOrder(userId,
					placeOrderResp.getTradingId());

			// 支付网关支付回调交易
			SQPayGateWayCallService.DGSQNotifyCall(
					String.valueOf(thirdTradingId),
					totalPrice.subtract(BigDecimal.ZERO).toString(),
					userId.intValue(), BigDecimal.ZERO.toPlainString());

			Thread.sleep(5000);

			Long paymentId = orderShardingWapper.selectOrderbyOrderId(orderId)
					.getPaymentId();
			
			PaymentPo payment = orderShardingWapper.selectPaymentById(paymentId);

			ShenqiSettlementService.onHpSettled(paymentId, payment, null, 1);

			userConfirmApplyRefundReq.setOrderId(orderId);
			userConfirmApplyRefundReq.setUserId(userId);

			userConfirmApplyRefundCall.setData(userConfirmApplyRefundReq);
			userConfirmApplyRefundCall.callService();

			// 退款提交到网关
			UserRefundFundDetailPo record = new UserRefundFundDetailPo();

			Calendar calendar = Calendar.getInstance();
			calendar.setTime(new Date());
			calendar.add(Calendar.MINUTE, -6);

			record.setPaymentId(paymentId);
			record.setUpdateTime(calendar.getTime());

			orderShardingWapper.userRefundFundDetailMapper
					.updateByPrimaryKeySelective(record);

			RefundService.supplementRefund(orderId);

			// 支付网关退款回调
			SQPayGateWayCallService.refundNotifyCall("13", paymentId.toString(),
					userId.intValue());

			Logger.comment("userId: " + userId + ", orderId: " + orderId);
			Logger.verifyEquals("true",
					userConfirmApplyRefundCall.getString("success"), "验证success");

			this.verify(userId, false, null);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	public static void main(String[] args) throws ClientProtocolException,
			IOException {
	}
}
